// $Id: ptr_access.hpp 2 2009-09-02 08:47:42Z joseph2002 $
/*
 * Copyright 2009 Joseph Wu
 * Distributed under the Boost Software License, Version 1.0.
 * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
 *
 * For more information, see http://xpcomplus.sourceforge.net
 */

#ifndef XPCOM_DETAIL_PTR_ACCESS_HPP
#define XPCOM_DETAIL_PTR_ACCESS_HPP

#include <xpcom/config.hpp>
#include <xpcom/ptr.hpp>

#ifdef BOOST_HAS_ABI_HEADERS
#include BOOST_ABI_PREFIX
#endif

namespace xpcom {
namespace detail {

//
// Helper class for access ptr data.
//
template <typename Ptr>
struct ptr_access
{
    typedef Ptr ptr_type;
    typedef typename Ptr::element_type element_type;
    typedef element_type* pointer;

    XPCOM_FORCEINLINE
    static const pointer& ptr(const Ptr& p)
    {
        return p.p_;
    }

    XPCOM_FORCEINLINE
    static pointer& ptr(Ptr& p)
    {
        return p.p_;
    }
};

template <typename T>
XPCOM_FORCEINLINE const typename ptr_access<ref_ptr<T> >::pointer&
ptr_access_ptr(const ref_ptr<T>& p)
{
    return ptr_access<ref_ptr<T> >::ptr(p);
}

template <typename T>
XPCOM_FORCEINLINE typename ptr_access<ref_ptr<T> >::pointer&
ptr_access_ptr(ref_ptr<T>& p)
{
    return ptr_access<ref_ptr<T> >::ptr(p);
}

template <typename T>
XPCOM_FORCEINLINE const typename ptr_access<noref_ptr<T> >::pointer&
ptr_access_ptr(const noref_ptr<T>& p)
{
    return ptr_access<noref_ptr<T> >::ptr(p);
}

template <typename T>
XPCOM_FORCEINLINE typename ptr_access<noref_ptr<T> >::pointer&
ptr_access_ptr(noref_ptr<T>& p)
{
    return ptr_access<noref_ptr<T> >::ptr(p);
}

} // namespace xpcom::detail
} // namespace xpcom

#ifdef BOOST_HAS_ABI_HEADERS
#include BOOST_ABI_SUFFIX
#endif

#endif // XPCOM_DETAIL_PTR_ACCESS_HPP
